package gui;

import db.DBManager;
import struct.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.awt.Frame;

/**
 * A class to edit a household.
 * @author Sarah Wegner
 */
public class EditHouseholdGui extends javax.swing.JFrame {

    /** Variables*/
    Object[] editRecord;
    String[] familyKey = new String[2];
    String[] familyAttributes;//list of all orig. family attributes
    Family family;//keep the original family object
    ArrayList<Dependent> dependent;//list of all orig. dependents and their attributes
    int depSize;
    ArrayList<Adult> adult;//list of all orig. adults and their attributes
    int adultSize;
    ArrayList<Address> address;//list of all orig. addresses and their attribs
    int addressSize;
    ArrayList<Money> money; //list of all orig. contributions and attributes
    int moneySize;
    ArrayList<Interest> interests;//list of orig. ministry 0000000000000000000000000000000000000000000000000000000000000       interests
    int interestSize;
    ArrayList<History> histories;//list of orig. ministry histories
    int historySize;

    ArrayList<Integer> adultAddedList = new ArrayList();//keep track of adults added
    ArrayList<Integer> adultDeletedList = new ArrayList();//keep track of adults deleted
    ArrayList<Integer> adultUpdatedList = new ArrayList();//keep track of adults updated

    ArrayList<Integer> depAddedList = new ArrayList();//keep track of dep's added
    ArrayList<Integer> depDeletedList = new ArrayList();//keep track of dep's deleted
    ArrayList<Integer> depUpdatedList = new ArrayList();//keep track of dep's updated

    ArrayList<Integer> addressAddedList = new ArrayList();//keep track of add's added
    ArrayList<Integer> addressDeletedList = new ArrayList();//keep track of add's deleted
    ArrayList<Integer> addressUpdatedList = new ArrayList();//keep track of add's updated

    ArrayList<Integer> moneyAddedList = new ArrayList();//keep track of money added
    ArrayList<Integer> moneyDeletedList = new ArrayList();//keep track of money deleted
    ArrayList<Integer> moneyUpdatedList = new ArrayList();//keep track of money updated

    ArrayList<Integer> interestAddedList = new ArrayList();//keep track of interests added
    ArrayList<Integer> interestDeletedList = new ArrayList();//keep track of interests deleted
    ArrayList<Integer> interestUpdatedList = new ArrayList();//keep track of interests updated

    ArrayList<Integer> historyAddedList = new ArrayList();//keep track of History added
    ArrayList<Integer> historyDeletedList = new ArrayList();//keep track of History deleted
    ArrayList<Integer> historyUpdatedList = new ArrayList();//keep track of History updated

    /** Creates new form EditHouseholdGui */
    public EditHouseholdGui(String[] familyAttribs) {
        initComponents();//initialize gui components
        initFields(familyAttribs);//initialize data in gui
        initArrayLists();//initialize add/update/delete arraylists to keep track of transactions
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jSeparator2 = new javax.swing.JSeparator();
        btSave = new javax.swing.JButton();
        btCancel = new javax.swing.JButton();
        btAddRow = new javax.swing.JButton();
        btRemoveRow = new javax.swing.JButton();
        lblAddNewHousehold = new javax.swing.JLabel();
        tabbedPane = new javax.swing.JTabbedPane();
        tabAdult = new javax.swing.JScrollPane();
        jAdultTable = new javax.swing.JTable();
        jDependentsTab = new javax.swing.JScrollPane();
        jDependentTable = new javax.swing.JTable();
        jFamilyTab = new javax.swing.JScrollPane();
        jFamilyInformationTable = new javax.swing.JTable();
        jAddressTab = new javax.swing.JScrollPane();
        jAddressTable = new javax.swing.JTable();
        jContributionsTab = new javax.swing.JScrollPane();
        jContributionTable = new javax.swing.JTable();
        jMinistryInterestTab = new javax.swing.JScrollPane();
        jMinistryInterestTable = new javax.swing.JTable();
        jScrollPane1 = new javax.swing.JScrollPane();
        jMinistryHistoryTable = new javax.swing.JTable();
        btEditInd = new javax.swing.JButton();
        btDeleteHousehold = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        jSeparator2.setForeground(new java.awt.Color(0, 153, 0));

        btSave.setText("Save");
        btSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btSaveActionPerformed(evt);
            }
        });

        btCancel.setText("Cancel");
        btCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btCancelActionPerformed(evt);
            }
        });

        btAddRow.setText("Add Row");
        btAddRow.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btAddRowActionPerformed(evt);
            }
        });

        btRemoveRow.setText("Delete Row");
        btRemoveRow.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btRemoveRowActionPerformed(evt);
            }
        });

        lblAddNewHousehold.setFont(new java.awt.Font("Tahoma", 0, 14));
        lblAddNewHousehold.setText("Edit Household");

        tabbedPane.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                tabbedPaneStateChanged(evt);
            }
        });

        jAdultTable.setBackground(new java.awt.Color(230, 230, 255));
        jAdultTable.setModel(adultTableModel);
        jAdultTable.setName("editAdult"); // NOI18N
        tabAdult.setViewportView(jAdultTable);

        tabbedPane.addTab("Adults", tabAdult);

        jDependentTable.setBackground(new java.awt.Color(230, 230, 255));
        jDependentTable.setModel(dependentTableModel);
        jDependentTable.setName("editDependent"); // NOI18N
        jDependentsTab.setViewportView(jDependentTable);

        tabbedPane.addTab("Dependents", jDependentsTab);

        jFamilyInformationTable.setBackground(new java.awt.Color(230, 230, 255));
        jFamilyInformationTable.setModel(familyTableModel);
        jFamilyInformationTable.setName("editFamilyInformation"); // NOI18N
        jFamilyTab.setViewportView(jFamilyInformationTable);

        tabbedPane.addTab("Family Information", jFamilyTab);

        jAddressTable.setBackground(new java.awt.Color(230, 230, 255));
        jAddressTable.setModel(addressTableModel);
        jAddressTable.setName("editAddress"); // NOI18N
        jAddressTab.setViewportView(jAddressTable);

        tabbedPane.addTab("Addresses", jAddressTab);

        jContributionTable.setBackground(new java.awt.Color(230, 230, 255));
        jContributionTable.setModel(contributionTableModel);
        jContributionTable.setName("editContribution"); // NOI18N
        jContributionsTab.setViewportView(jContributionTable);

        tabbedPane.addTab("Contributions", jContributionsTab);

        jMinistryInterestTable.setBackground(new java.awt.Color(230, 230, 255));
        jMinistryInterestTable.setModel(ministryInterestTableModel);
        jMinistryInterestTable.setName("editInterest"); // NOI18N
        jMinistryInterestTab.setViewportView(jMinistryInterestTable);

        tabbedPane.addTab("Ministry Interest", jMinistryInterestTab);

        jMinistryHistoryTable.setBackground(new java.awt.Color(230, 230, 255));
        jMinistryHistoryTable.setModel(ministryHistoryTableModel);
        jMinistryHistoryTable.setName("editHistory"); // NOI18N
        jScrollPane1.setViewportView(jMinistryHistoryTable);

        tabbedPane.addTab("Ministry History", jScrollPane1);

        btEditInd.setText("Edit Individual");
        btEditInd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btEditIndActionPerformed(evt);
            }
        });

        btDeleteHousehold.setText("Delete Household");
        btDeleteHousehold.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btDeleteHouseholdActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lblAddNewHousehold)
                    .addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 1310, Short.MAX_VALUE)
                    .addComponent(tabbedPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 1310, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(btDeleteHousehold)
                        .addGap(632, 632, 632)
                        .addComponent(btEditInd)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btRemoveRow)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btAddRow)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btCancel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btSave, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblAddNewHousehold)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 481, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btSave)
                    .addComponent(btCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btAddRow)
                    .addComponent(btRemoveRow)
                    .addComponent(btEditInd)
                    .addComponent(btDeleteHousehold))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btSaveActionPerformed

        //Stop Cell editing on all Tabs
        stopCellEditing(jAdultTable);
        stopCellEditing(jDependentTable);
        stopCellEditing(jFamilyInformationTable);
        stopCellEditing(jAddressTable);
        stopCellEditing(jContributionTable);
        stopCellEditing(jMinistryInterestTable);
        stopCellEditing(jMinistryHistoryTable);

        //1. Check for required Fields in all Tabs
        String requiredFields = verifyRequiredFields();
        //2. Check for duplicate rows in all Tabs
        String dupTabs = verifyDuplicateRows();
        //3. Check for proper date format in all Tabs
        String dateFields = verifyDateFields();
        //4. Check for proper phone format in all Tabs
        String phoneFields = verifyPhoneFields();
        //5. Check for proper state format
        boolean stateFields = verifyStateFields();
        //6. Check for proper zipcode format
        boolean zipFields = verifyZipFields();
        //7. Check for proper money formats
        boolean moneyFields = verifyMoneyFormat();
        //8. Check for no duplicate entries for added rows in the database
        String duplicateDBAdded = verifyAddedItemsExist();
        //9. Check for no duplicate entries for updated rows in the database
        String duplicateDBUpdated = verifyUpdatedItemsExist();

//        //Add the duplicate strings together.
//        String duplicateDB = "Added Rows: " + "\n" + duplicateDBAdded
//                    + "\n" + "Updated Rows: " + "\n" + duplicateDBUpdate;

        if(!requiredFields.equals("")){
            JOptionPane.showMessageDialog(null, "Please complete the "
                    + "required fields for the following tabs: "
                    + "\n" + requiredFields + "\n\n" +
                    "Note: If a row is empty and is not needed in a particular table, delete"
                    + " the row, then click the 'Save' button. All required"
                    + " fields are marked with a '*'.",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }//if
        else if(!dupTabs.equals(""))
        {
            JOptionPane.showMessageDialog(null, "The following tabs"
                    + " have duplicate rows: "
                    + "\n" + dupTabs + "\n" + "Please remove the duplicate rows before continuing.",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }//if
        else if(!dateFields.equals(""))
        {
            JOptionPane.showMessageDialog(null, "The Tabs listed below have dates "
                    + "in incorrect format. Please use MM/DD/YYYY."
                    + "\n" + dateFields, "Save Error", JOptionPane.WARNING_MESSAGE);
        }//if
        else if(!phoneFields.equals("")){
            JOptionPane.showMessageDialog(null, "The Tabs listed below have phone numbers "
                    + "in incorrect format. Please use (XXX)XXX-XXXX." + "\n" +"Ex: (920)555-5491"
                    + "\n" + phoneFields, "Save Error", JOptionPane.WARNING_MESSAGE);
        }
        else if(!stateFields){
            JOptionPane.showMessageDialog(null, "The Address Tab has a 'State' field "
                    + "in incorrect format. Please use XX." + "\n" +"Ex: WI",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }
        else if(!zipFields){
            JOptionPane.showMessageDialog(null, "The Address Tab has a 'Zipcode' field "
                    + "in incorrect format. Please use the 5 or 9 digit format."
                    + "\n" +"Ex: 54952 or 54952-1234",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }
        else if(!moneyFields){
            JOptionPane.showMessageDialog(null, "The Contribution Tab has a money field "
                    + "in incorrect format. Please use the following format, 'XX.XX'."
                    + "\n" +"Ex: 1.00 or 120.25",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }
        else if(!duplicateDBAdded.equals("")){
            JOptionPane.showMessageDialog(null,"The Added Entries listed below already exist in the database." +
                        "\n" + duplicateDBAdded,
                        "Save Error",
                        JOptionPane.WARNING_MESSAGE);
        }
        else if(!duplicateDBUpdated.equals("")){
            JOptionPane.showMessageDialog(null,"The Updated Entries listed below already exist in the database." +
                        "\n" + duplicateDBUpdated,
                        "Save Error",
                        JOptionPane.WARNING_MESSAGE);
        }
        else{
            save();
        }//else
}//GEN-LAST:event_btSaveActionPerformed

    private void btCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btCancelActionPerformed
       int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                "you would like to close "+ "\n"+ "this window without saving?",
                "Cancel", JOptionPane.YES_NO_OPTION);
        if (answer == JOptionPane.YES_OPTION) {
            // User clicked YES.
            this.dispose();
        } //else if (answer == JOptionPane.NO_OPTION)
         // User clicked NO. Do nothing.
}//GEN-LAST:event_btCancelActionPerformed

    private void btAddRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btAddRowActionPerformed
        //get index of selected tab
        int tabIndex = tabbedPane.getSelectedIndex();
        //Only 2 adults are allowed per family
        //Disable add row button if adults > 2
        if(tabIndex == 0){
            int countAdult = adultTableModel.getRowCount();
            int countDelete = 0;
            for(int i = 0; i < countAdult; i++){
                Object deletedCellValue = jAdultTable.getValueAt(i, 10);
                if((Boolean)deletedCellValue && deletedCellValue != null){
                    countDelete++;
                }//if
            }//for
            
            int addedAdults = countAdult-countDelete;
            if((addedAdults < 2) && (addedAdults > 0)){
                adultAddedList.add((Integer)countAdult);//the index of the new row will be the same as the orig. row count
                adultTableModel.addRow(new Object[] {"","","","","","","","","","",false});
            }//else
            else{
                JOptionPane.showMessageDialog(null,
                    "A family can only have two adult records.", "Add Adult",
                    JOptionPane.WARNING_MESSAGE);
            }
        }//tabIndex = 0
        else if(tabIndex == 1){
            //the index of the new row will be the same as the orig. row count
            depAddedList.add((Integer)dependentTableModel.getRowCount());
            dependentTableModel.addRow(new Object[] {"","","","","","","",false});
        }//tabIndex = 1
        else if(tabIndex == 2){
            //do nothing only 1 record needed
           JOptionPane.showMessageDialog(null,
                    "A family only needs one family information record.", "Add Adult",
                    JOptionPane.WARNING_MESSAGE);
        }//tabIndex = 2
        else if(tabIndex == 3){
            //the index of the new row will be the same as the orig. row count
            addressAddedList.add((Integer)addressTableModel.getRowCount());
            addressTableModel.addRow(new Object[] {"","","","","",false,"",false});
        }//tabIndex = 3
        else if(tabIndex == 4){
            //the index of the new row will be the same as the orig. row count
            moneyAddedList.add((Integer)contributionTableModel.getRowCount());
            contributionTableModel.addRow(new Object[] {"","","","",false});
        }//tabIndex = 4
        else if(tabIndex == 5){
            //the index of the new row will be the same as the orig. row count
            interestAddedList.add((Integer)ministryInterestTableModel.getRowCount());
            ministryInterestTableModel.addRow(new Object[] {"","",false});
        }//tabIndex = 5
        else if(tabIndex == 6){
            //the index of the new row will be the same as the orig. row count
            historyAddedList.add((Integer)ministryHistoryTableModel.getRowCount());
            ministryHistoryTableModel.addRow(new Object[] {"","",false});
        }//tabIndex = 6
}//GEN-LAST:event_btAddRowActionPerformed

    private void btRemoveRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btRemoveRowActionPerformed

        //Remove row in table if the user does not find it necessary
        //index of deleted col
        int deletedCol;
        //get index of selected tab
        int tabIndex = tabbedPane.getSelectedIndex();
        if(tabIndex == 0){
            int countAdult = adultTableModel.getRowCount();
            int countDelete = 0;
            for(int i = 0; i < countAdult; i++){
                Object deletedCellValue = jAdultTable.getValueAt(i, 10);
                if((Boolean)deletedCellValue && deletedCellValue != null){
                    countDelete++;
                }//if
            }//for
            int adults = countAdult-countDelete;

            if(adults == 2){
                int row = jAdultTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        //adultTableModel.removeRow(row);
                        /*disable selected row & color different*/
                        deletedCol = jAdultTable.getColumnCount()-1;
                        jAdultTable.setValueAt(true, row, deletedCol);
                        jAdultTable.changeSelection(row, deletedCol, false, false);
                        jAdultTable.requestFocus();

                        /*delete from update and add lists*/
                        if(adultUpdatedList.contains(row)){
                            adultUpdatedList.remove((Integer)row);
                            /*add to delete row index*/
                            adultDeletedList.add((Integer)row);

                        }//if
                        if(adultAddedList.contains(row)){
                            adultAddedList.remove((Integer)row);
                        }//if
                    }//If Yes Delete; else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row before removing one.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "You must have at least one adult per family.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 0
        ////////////////////////////////////////////////////////////////////////
        else if(tabIndex == 1){
            int depRowCount = jDependentTable.getRowCount();
            //confirm delete of row.
            if(depRowCount > 0){
                int row = jDependentTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        //dependentTableModel.removeRow(row);
                        /*disable selected row & color different*/
                        deletedCol = jDependentTable.getColumnCount()-1;
                        jDependentTable.setValueAt(true, row, deletedCol);
                        jDependentTable.changeSelection(row, deletedCol, false, false);
                        jDependentTable.requestFocus();

                        /*delete from update and add lists*/
                        if(depUpdatedList.contains((Integer)row)){
                            depUpdatedList.remove((Integer)row);

                            /*add to delete row index*/
                            depDeletedList.add((Integer)row);
                        }//if
                        if(depAddedList.contains((Integer)row)){
                            depAddedList.remove((Integer)row);
                        }//if
                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to remove first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "Please select a row to remove first.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 1
        ////////////////////////////////////////////////////////////////////////
        else if(tabIndex == 2){
            //do nothing You cannot delete family row
            JOptionPane.showMessageDialog(null,
                    "A family must have family information.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
        }//tabIndex = 2
        ////////////////////////////////////////////////////////////////////////
        else if(tabIndex == 3){
            int countAddress = addressTableModel.getRowCount();
            int countDelete = 0;
            deletedCol = jAddressTable.getColumnCount()-1;
            for(int i = 0; i < countAddress; i++){
                Object deletedCellValue = jAddressTable.getValueAt(i, deletedCol);
                if((Boolean)deletedCellValue && deletedCellValue != null){
                    countDelete++;
                }//if
            }//for
            int addressRows = countAddress-countDelete;
            if(addressRows > 1){
                int row = jAddressTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        /*disable selected row & color different*/
                        jAddressTable.setValueAt(true, row, deletedCol);
                        jAddressTable.changeSelection(row, deletedCol, false, false);
                        jAddressTable.requestFocus();

                        /*delete from update and add lists*/
                        if(addressUpdatedList.contains((Integer)row)){
                            addressUpdatedList.remove((Integer)row);
                            /*add to delete row index*/
                            addressDeletedList.add((Integer)row);
                        }//if
                        if(addressAddedList.contains((Integer)row)){
                            addressAddedList.remove((Integer)row);
                        }//if
                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to remove first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "A family must have at least one address.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 3
        ////////////////////////////////////////////////////////////////////////
        else if(tabIndex == 4){
            int contributionRowCount = jContributionTable.getRowCount();
            //confirm delete of row.
            if(contributionRowCount > 0){
                int row = jContributionTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        /*disable selected row & color different*/
                        deletedCol = jContributionTable.getColumnCount()-1;
                        jContributionTable.setValueAt(true, row, deletedCol);
                        jContributionTable.changeSelection(row, deletedCol, false, false);
                        jContributionTable.requestFocus();

                        /*delete from update and add lists*/
                        if(moneyUpdatedList.contains((Integer)row)){
                            moneyUpdatedList.remove((Integer)row);

                            /*add to delete row index*/
                            moneyDeletedList.add((Integer)row);
                        }//if
                        if(moneyAddedList.contains((Integer)row)){
                            moneyAddedList.remove((Integer)row);
                        }//if
                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to remove first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "Please select a row to remove first.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 4
        ////////////////////////////////////////////////////////////////////////
        else if(tabIndex == 5){
            int interestRowCount = jMinistryInterestTable.getRowCount();
            //confirm delete of row.
            if(interestRowCount > 0){
                int row = jMinistryInterestTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        /*disable selected row & color different*/
                        deletedCol = jMinistryInterestTable.getColumnCount()-1;
                        jMinistryInterestTable.setValueAt(true, row, deletedCol);
                        jMinistryInterestTable.changeSelection(row, deletedCol, false, false);
                        jMinistryInterestTable.requestFocus();

                        /*delete from update and add lists*/
                        if(interestUpdatedList.contains((Integer)row)){
                            interestUpdatedList.remove((Integer)row);

                            /*add to delete row index*/
                            interestDeletedList.add((Integer)row);
                        }//if
                        if(interestAddedList.contains((Integer)row)){
                            interestAddedList.remove((Integer)row);
                        }//if

                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to removing first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "Please select a row to removing first.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 5
        ////////////////////////////////////////////////////////////////////////
        else if(tabIndex == 6){
            int historyRowCount = jMinistryHistoryTable.getRowCount();
            //confirm delete of row.
            if(historyRowCount > 0){
                int row = jMinistryHistoryTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        /*disable selected row & color different*/
                        deletedCol = jMinistryHistoryTable.getColumnCount()-1;
                        jMinistryHistoryTable.setValueAt(true, row, deletedCol);
                        jMinistryHistoryTable.changeSelection(row, deletedCol, false, false);
                        jMinistryHistoryTable.requestFocus();

                        /*delete from update and add lists*/
                        if(historyUpdatedList.contains((Integer)row)){
                            historyUpdatedList.remove((Integer)row);

                            /*add to delete row index*/
                            historyDeletedList.add((Integer)row);
                        }//if
                        if(historyAddedList.contains((Integer)row)){
                            historyAddedList.remove((Integer)row);
                        }//if

                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to removing first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "Please select a row to removing first.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 6
}//GEN-LAST:event_btRemoveRowActionPerformed

    private void btEditIndActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btEditIndActionPerformed
        Boolean adultSelected = false;
        Boolean depSelected = false;
        int tabbedIndex = tabbedPane.getSelectedIndex();
        int rowIndex = -1;

        if(tabbedIndex == 0){
            adultSelected = true;
            depSelected = false;
            if(adultUpdatedList.contains((Integer)jAdultTable.getSelectedRow())){
                rowIndex = jAdultTable.getSelectedRow();
            }
        }//if-adults
        else if (tabbedIndex == 1){
            depSelected = true;
            adultSelected = false;
            if(depUpdatedList.contains((Integer)jDependentTable.getSelectedRow())){
                rowIndex = jDependentTable.getSelectedRow();
            }
        }//if-dependents


        if(rowIndex >= 0){

            if(adultSelected){
                Adult editAdult = adult.get(rowIndex);
                String[] adultKey = editAdult.getKey();
                EditAdult.run(adultKey);
            }//if
            else if(depSelected){
                Dependent editDependent = dependent.get(rowIndex);
                String[] depKey = editDependent.getKey();
                EditDependent.run(depKey);
            }//else
        }//if - rowIndex > 0
    }//GEN-LAST:event_btEditIndActionPerformed

    private void btDeleteHouseholdActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btDeleteHouseholdActionPerformed
        try{
            DBManager dbManager = new DBManager();
            boolean deleteHousehold;

            int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this family?",
                        "Delete", JOptionPane.YES_NO_OPTION);
            if(answer == JOptionPane.YES_OPTION){
                deleteHousehold = dbManager.deleteHousehold(adult, dependent, family, address, money, interests, histories);
                if(deleteHousehold){
                    JOptionPane.showMessageDialog(null,
                            "You have successfully deleted this household!",
                            "Delete Household",JOptionPane.INFORMATION_MESSAGE);
                }//if
                else{
                    deleteSaveError("family");
                }//else
                this.dispose();
            }//if-yes
            //else- do nothing.
        }//try
        catch(Exception ex){
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "deleting this family record from the database."
                    +"\n"+ "Please contact your Database Administrator,"
                    + " a.k.a Thomas Naps, for help if this persists."
                    +"\n"+ "btDeleteHouseholdActionPerformed() Method: EditHouseholdGui.java",
                    "Database Save Error", JOptionPane.ERROR_MESSAGE);
            ex.printStackTrace();
        }//catch
    }//GEN-LAST:event_btDeleteHouseholdActionPerformed

    /**
     * When a tab selection is changed,
     * set up information for the user based on other tabs
     * @param evt
     */
    private void tabbedPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabbedPaneStateChanged
         //Stop Cell editing on all Tabs
        stopCellEditing(jAdultTable);
        stopCellEditing(jDependentTable);
        stopCellEditing(jFamilyInformationTable);
        stopCellEditing(jAddressTable);
        stopCellEditing(jContributionTable);
        stopCellEditing(jMinistryInterestTable);
        stopCellEditing(jMinistryHistoryTable);


        int tabIndex = tabbedPane.getSelectedIndex();
        //Set the "Head of House" column based on adult input.
        if(tabIndex == 2){            
            //Get List of Adults
            ArrayList<String> headHouseList = new ArrayList();
            for(int i = 0; i < adultTableModel.getRowCount(); i++ ){
                if(adultTableModel.getValueAt(i, 0)!= null
                        && (((Boolean)adultTableModel.getValueAt(i, adultTableModel.getColumnCount()-1)) == false)){
                    headHouseList.add(adultTableModel.getValueAt(i, 0).toString());
                }//if
            }//for

            //copy adult arraylist to the array, since combo box editor calls for an array
            String[] headHouse = new String[headHouseList.size()+1];
            headHouse[0] = "";//set first element to be an empty string so user must choose a value.
            for(int i = 0; i < headHouseList.size(); i++){
                headHouse[i+1] = headHouseList.get(i);
            }//for

            //set combo box
            TableColumn colHeadHouse = jFamilyInformationTable.getColumnModel().getColumn(2);
            colHeadHouse.setCellEditor(new MyComboBoxEditor(headHouse));
            colHeadHouse.setCellRenderer(new MyComboBoxRenderer(headHouse));
            jFamilyInformationTable.setRowHeight(20);

            //Set Focus to First Cell
            jFamilyInformationTable.changeSelection(0, 0, false, false);
            jFamilyInformationTable.requestFocus();
            stopCellEditing(jFamilyInformationTable);
        }//if
    }//GEN-LAST:event_tabbedPaneStateChanged


   /**
    * Runs Edit Household Gui
    */
    public static void run(String[] familyAttribs) {
                new EditHouseholdGui(familyAttribs).setVisible(true);

    }//run

    /**
     * A method to initialize the fields to the editing record
     * @param familyAttribs - string array of family information
     */
    private void initFields(String[] familyAttribs){
        int deletedCol;//used to keep track of the index of the "Deleted" column

        familyKey[0] = familyAttribs[0];
        familyKey[1] = familyAttribs[1];

        familyAttributes = new String[familyAttribs.length];
        System.arraycopy(familyAttribs, 0, familyAttributes, 0, familyAttribs.length);


        //set the values of the editing family in the Family Info tab
        for(int i = 0; i < familyAttributes.length; i++){
            if(!familyAttributes[i].equalsIgnoreCase("null")){
                if(familyAttributes[i].equalsIgnoreCase("true")){
                    familyTableModel.setValueAt(true, 0, i);   
                }//if
                else if(familyAttributes[i].equalsIgnoreCase("false")){
                    familyTableModel.setValueAt(false, 0, i);
                }//else if
                else{
                    familyTableModel.setValueAt(familyAttributes[i], 0, i);
                }//else
            }//if
        }//fore-i

        try{
            DBManager dbManager = new DBManager();

            //Get Ministry Names
            ArrayList<String> ministryNames = dbManager.getMinistryNames(true);
            String[] ministryNamesArray = new String[ministryNames.size()+1];

            //copy ministry names into string array
            ministryNamesArray[0] = "";
            for(int m = 0; m < ministryNames.size(); m++){
                ministryNamesArray[m+1] = ministryNames.get(m);
            }//for
            
            //set "Ministry Name" column of Ministry Interest Tab to be
            //a drop-down of all ministries
            setComboBoxRenderer(jMinistryInterestTable,ministryNamesArray);
            setComboBoxRenderer(jMinistryHistoryTable,ministryNamesArray);

            //Set "Religeous Schooling" column
            String[] school = {"","Religious School", "Day School", "Other"};
            TableColumn colSchool = jDependentTable.getColumnModel().getColumn(4);
            colSchool.setCellEditor(new MyComboBoxEditor(school));
            colSchool.setCellRenderer(new MyComboBoxRenderer(school));
            jDependentTable.setRowHeight(20);

            //set "Deleted Column Width for each tab
            setDeletedCellWidth(jAdultTable,50);
            setDeletedCellWidth(jDependentTable,50);
            setDeletedCellWidth(jAddressTable,50);
            setDeletedCellWidth(jContributionTable,50);
            setDeletedCellWidth(jMinistryInterestTable,50);
            setDeletedCellWidth(jMinistryHistoryTable,50);

            //set cell renderers to change color of a deleted row
            //Adult
            for(int i = 0; i < jAdultTable.getColumnCount()-1; i++){
                setCellRenderer(jAdultTable,i);
            }//for
            
            //Dependent
            for(int i = 0; i < jDependentTable.getColumnCount()-1; i++){
                if(i != 4){
                    setCellRenderer(jDependentTable,i);
                }//if
            }//for

            //Address
            for(int i = 0; i < jAddressTable.getColumnCount()-1; i++){
                if(i != 5){
                    setCellRenderer(jAddressTable,i);
                }//if- 5="Is Current Mailing" boolean; Don't want to set this field
            }//for
            
            //Contributions
            for(int i = 0; i < jContributionTable.getColumnCount()-1; i++){
                setCellRenderer(jContributionTable,i);
            }//for
            

            //set each table not to have movable columns
            dontMoveColumns(jAdultTable);
            dontMoveColumns(jDependentTable);
            dontMoveColumns(jFamilyInformationTable);
            dontMoveColumns(jAddressTable);
            dontMoveColumns(jContributionTable);
            dontMoveColumns(jMinistryInterestTable);
            dontMoveColumns(jMinistryHistoryTable);

            ////////////////////////////////////////////////////////////////////
            /*Get Family*/
            ////////////////////////////////////////////////////////////////////
            family = dbManager.getFamily(familyKey[0], familyKey[1]);

            ////////////////////////////////////////////////////////////////////
            /*get Dependents for a family record*/
            ////////////////////////////////////////////////////////////////////
            dependent = dbManager.getDependents(familyKey[0], familyKey[1]);
            Dependent dependentObj;
            String[] depAttribs;

            //remove null from size() method
            depSize = getSize(dependent);
            
            //set dependents in dep. table
            dependentTableModel.setRowCount(depSize);
            for(int i = 0; i < depSize; i++){
                dependentObj = dependent.get(i);
                depAttribs = (String[]) dependentObj.getAttributes();
                for(int j = 0; j < depAttribs.length; j++){
                    if(depAttribs[j]!= null){
                        dependentTableModel.setValueAt(depAttribs[j], i, j);
                    }//if
                    else{
                        dependentTableModel.setValueAt("", i, j);
                    }//else
                }//for-j
            }//for-i

            //set Value of "Deleted" cell
            deletedCol = jDependentTable.getColumnCount()-1;
            for(int i = 0; i < depSize; i++){
                dependentTableModel.setValueAt((Boolean)false, i, deletedCol);
            }

            ////////////////////////////////////////////////////////////////////
            /*get Adults for a family record*/
            ////////////////////////////////////////////////////////////////////
            adult = dbManager.getAdults(familyKey[0], familyKey[1]);
            Adult adultObj;
            String[] adultAttribs;
            
            adultSize = getSize(adult);

            //set adults in adult table
            adultTableModel.setRowCount(adultSize);
            for(int i = 0; i < adultSize; i++){
                adultObj = adult.get(i);
                adultAttribs = (String[]) adultObj.getAttributes();
                for(int j = 0; j < adultAttribs.length; j++){
                    if(adultAttribs[j]!= null){
                        adultTableModel.setValueAt(adultAttribs[j], i, j);
                    }
                    else{
                        adultTableModel.setValueAt("", i, j);
                    }
                }//for-j
            }//for-i
            //set Value of "Deleted" cell
            deletedCol = jAdultTable.getColumnCount()-1;
            for(int i = 0; i < adultSize; i++){
                adultTableModel.setValueAt(false, i, deletedCol);
            }

            ////////////////////////////////////////////////////////////////////
            /*get addresses for family record*/
            ////////////////////////////////////////////////////////////////////
            address = dbManager.getAddresses(familyKey[0], familyKey[1]);
            Address addressObj;
            Object[] addressAttribsObj;
            String[] addressAttribs = new String[addressTableModel.getColumnCount()-1];//-1 b/c we don't count the "delete" column
            
            addressSize = getSize(address);

            //set addresses in address table
            addressTableModel.setRowCount(addressSize);
            for(int i = 0; i < addressSize; i++){
                addressObj = address.get(i);
                addressAttribsObj = addressObj.getAttributes();
                addressAttribs[0] = addressAttribsObj[0]+"";
                addressAttribs[1] = addressAttribsObj[1] +"";
                addressAttribs[2] = addressAttribsObj[2] +"";
                addressAttribs[3] = addressAttribsObj[3] +"";
                addressAttribs[4] = addressAttribsObj[4] +"";
                //addressAttribs[5] is a boolean -> keep as addressAttribsObj[5]
                addressAttribs[6] = addressAttribsObj[6] +"";

                //set address data in address tab
                for(int j = 0; j < addressAttribs.length; j++){
                    //set boolean column
                    if(j == 5 && addressAttribsObj[5] != null){
                        addressTableModel.setValueAt(addressAttribsObj[5], i, j);
                    }//if
                    //otherwise set string columns
                    else if(!addressAttribs[j].equalsIgnoreCase("null")){
                            addressTableModel.setValueAt(addressAttribs[j], i, j);
                    }//else
                    else{
                        addressTableModel.setValueAt("", i, j);
                    }
                }//for-j
            }//for-i

            //set Value of "Deleted" cell
            deletedCol = jAddressTable.getColumnCount()-1;
            for(int i = 0; i < addressSize; i++){
                addressTableModel.setValueAt(false, i, deletedCol);
            }

            ////////////////////////////////////////////////////////////////////
            /*get contributions for a family record*/
            ////////////////////////////////////////////////////////////////////
            money = dbManager.getMonies(familyKey[0],familyKey[1]);
            Money moneyObj;
            Object[] moneyAttribsObj;
            String[] moneyAttribs = new String[contributionTableModel.getColumnCount()-1];

            moneySize = getSize(money);

            //set values of a families contributions to the contribution jtable
            contributionTableModel.setRowCount(moneySize);
            for(int i = 0; i < moneySize; i++){
                moneyObj = money.get(i);
                moneyAttribsObj = moneyObj.getAttributes();
                moneyAttribs[0] = moneyAttribsObj[0]+"";
                moneyAttribs[1] = moneyAttribsObj[1] +"";
                moneyAttribs[2] = moneyAttribsObj[2] +"";
                moneyAttribs[3] = moneyAttribsObj[3] +"";

                //set money data in Contributions tab
                for(int j = 0; j < moneyAttribs.length; j++){
                    if(!moneyAttribs[j].equalsIgnoreCase("null")){
                        contributionTableModel.setValueAt(moneyAttribs[j], i, j);
                    }//if
                }//for-j
            }//for-i

            //set Value of "Deleted" cell
            deletedCol = jContributionTable.getColumnCount()-1;
            for(int i = 0; i < moneySize; i++){
                contributionTableModel.setValueAt(false, i, deletedCol);
            }//for

            ////////////////////////////////////////////////////////////////////
            /*Set Ministry Interest Fields*/
            ///////////////////////////////////////////////////////////////////
            interests = dbManager.getInterests("families", familyKey);
            interestSize = getSize(interests);

            ministryInterestTableModel.setRowCount(interestSize);
            jMinistryInterestTable.setRowHeight(20);
            Object[] interestAttribs;

            //set value of interest columns
            for(int j = 0; j < interestSize; j++){
                interestAttribs = interests.get(j).getAttributes();
                for(int m = 0; m < interestAttribs.length; m++){
                    if(interestAttribs[m] != null){
                        ministryInterestTableModel.setValueAt(interestAttribs[m]+"", j, m);
                    }//if
                    else{
                        ministryInterestTableModel.setValueAt("", j, m);
                    }
                }//for-m
            }//for-j

            //set Value of "Deleted" cell
            deletedCol = jMinistryInterestTable.getColumnCount()-1;
            for(int i = 0; i < interestSize; i++){
                ministryInterestTableModel.setValueAt(false, i, deletedCol);
            }//for

            //////////////////////////////////////////////////////////
            /*Set Ministry History Fields*/
            //////////////////////////////////////////////////////////
            histories = dbManager.getHistories("families", familyKey);
            historySize = getSize(histories);

            ministryHistoryTableModel.setRowCount(historySize);
            jMinistryHistoryTable.setRowHeight(20);
            Object[] historyAttribs;

            //set columns of history table
            for(int j = 0; j < historySize; j++){
                historyAttribs = histories.get(j).getAttributes();
                for(int m = 0; m < historyAttribs.length; m++){
                    if(historyAttribs[m] != null){
                        ministryHistoryTableModel.setValueAt(historyAttribs[m]+"", j, m);
                    }//if
                    else{
                        ministryHistoryTableModel.setValueAt("", j, m);
                    }
                }//for-m
            }//for-j

            //set Value of "Deleted" cell
            deletedCol = jMinistryHistoryTable.getColumnCount()-1;
            for(int i = 0; i < historySize; i++){
                ministryHistoryTableModel.setValueAt(false, i, deletedCol);
            }//for

        }//try
        catch(Exception ex){
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "initializing this record from the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists."
                            + "\n" + "initFields() Method: EditHouseholdGui.java",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
            ex.printStackTrace();
        }//catch

    }//initFields()

    /**
     * Initialize arraylists for add update and delete transactions for each
     * tab in the edithousehold gui
     */
    private void initArrayLists(){
         /**Initialize UpdatedList for each tab to include original data**/
        //Adults
        for(int i = 0; i < adultSize; i++){
            adultUpdatedList.add(i);
        }//for

        //Dependents
        for(int i = 0; i < depSize; i++){
            depUpdatedList.add(i);
        }//for

        //Addresses
        for(int i = 0; i < addressSize; i++){
            addressUpdatedList.add(i);
        }//for

        //Money
        for(int i = 0; i < moneySize; i++){
            moneyUpdatedList.add(i);
        }//for

        //Interests
        for(int i = 0; i < interestSize; i++){
            interestUpdatedList.add(i);
        }//for

        //History
        for(int i = 0; i < historySize; i++){
            historyUpdatedList.add(i);
        }//for

    }//initArrayList()

    /**
     * A method to stop cell editing of a JTable
     **/
    private void stopCellEditing(JTable table){
        if (table.getCellEditor() != null) {
            table.getCellEditor().stopCellEditing();
        }//if
    }//stopCellEditing

    /**
    * Method to make the columns in each tab non-re-sizable
    * @param table - table associated with each tab that will have non-re-sizable columns
    */
   private void dontMoveColumns(JTable table){
       //set Main Table to not be able to move columns
        JTableHeader header = table.getTableHeader();
        header.setReorderingAllowed(false);
   }//dontMoveColumns

    /**
     * Set the "Deleted" cell to a max width on tabs that
     * have the column
     * @param table - JTable that has this column
     * @param width - The max width of the column
     */
    private void setDeletedCellWidth(JTable table,int width){
        table.getColumnModel().getColumn(table.getColumnCount()-1).setMaxWidth(width);
    }//setDeletedCellWidth

    /**
     * Set a combo box renderer for tables with Combo Box Cells
     * @param table - table with cells that need a combo box
     * @param array - array of items you would like to put in the combo box
     */
    private void setComboBoxRenderer(JTable table, String[] array){
        //set "Ministry Name" column of Ministry Tab to be
        //a drop-down of all ministries
        int colCount = table.getColumnCount();
        TableColumn colHistory = table.getColumnModel().getColumn(0);
        colHistory.setCellEditor(new MyComboBoxEditor(array));
        colHistory.setCellRenderer(new MyComboBoxRenderer(array));
        table.setRowHeight(20);

        //set other columns that are not combo boxes
        for(int i = 1; i<colCount-1; i++){
            TableColumn otherCols = table.getColumnModel().getColumn(i);
            otherCols.setCellRenderer(new CellRenderer());
        }//for

    }//setComboBox Renderer

    /**
     * Set a cell renderer to change color when a row is marked delete
     * @param table - table with delete options
     */
    private void setCellRenderer(JTable table, int columnIndex){
        //for(int i = 0; i < table.getColumnCount(); i++){
            TableColumn col = table.getColumnModel().getColumn(columnIndex);
            col.setCellRenderer(new CellRenderer());
        //}//for
    }//setCellRenderer(JTable)

    /**
     * Saves updated information to database
     */
    private void save(){
        String rowsWithDups = "";
        boolean dupsExist = false;
        boolean saveSuccessful = false;
        try{
            DBManager dbManager = new DBManager();
            ///////////////////////////////////////////////////////////////////
            //1. Delete Objects from Database
            ///////////////////////////////////////////////////////////////////
            int adultDeletedSize = getSize(adultDeletedList);
            int depDeletedSize = getSize(depDeletedList);
            int addDeletedSize = getSize(addressDeletedList);
            int moneyDeletedSize = getSize(moneyDeletedList);
            int interestDeletedSize = getSize(interestDeletedList);
            int historyDeletedSize = getSize(historyDeletedList);

            //Delete Adults
            boolean deleteAdult;
            for(int i = 0; i < adultDeletedSize; i++){
                deleteAdult = false;
                int index = adultDeletedList.get(i);
                String[] adultKey = adult.get(index).getKey();
                deleteAdult = dbManager.deleteRecord("adults", adultKey, familyKey);
                if(!deleteAdult){
                    deleteSaveError("adult");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for
            //Delete Dependents
            boolean deleteDep;
            for(int i = 0; i < depDeletedSize; i++){
                deleteDep = false;
                int index = depDeletedList.get(i);
                String[] depKey = dependent.get(index).getKey();
                deleteDep = dbManager.deleteRecord("dependents", depKey, familyKey);
                if(!deleteDep){
                    deleteSaveError("dependent");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for
            //Delete Address
            boolean deleteAdd;
            for(int i = 0; i < addDeletedSize; i++){
                deleteAdd = false;
                int index = addressDeletedList.get(i);
                String[] addressKey = address.get(index).getKey();
                deleteAdd = dbManager.deleteRecord("address", addressKey, familyKey);
                if(!deleteAdd){
                    deleteSaveError("address");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Delete Money
            boolean deleteMoney;
            for(int i = 0; i < moneyDeletedSize; i++){
                deleteMoney = false;
                int index = moneyDeletedList.get(i);
                String[] moneyKey = money.get(index).getKey();
                deleteMoney = dbManager.deleteRecord("money", moneyKey, familyKey);
                if(!deleteMoney){
                    deleteSaveError("money");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Delete Interest
            boolean deleteInterest;
            for(int i = 0; i < interestDeletedSize; i++){
                deleteInterest = false;
                int index = interestDeletedList.get(i);
                String[] interestKey = interests.get(index).getKey();
                deleteInterest = dbManager.deleteRecord("interest", interestKey, familyKey);
                if(!deleteInterest){
                    deleteSaveError("interest");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for
            //Delete History
            boolean deleteHistory;
            for(int i = 0; i < historyDeletedSize; i++){
                deleteHistory = false;
                int index = historyDeletedList.get(i);
                String[] historyKey = histories.get(index).getKey();
                deleteHistory = dbManager.deleteRecord("history", historyKey, familyKey);
                if(!deleteHistory){
                    deleteSaveError("history");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            ////////////////////////////////////////////////////////////////////
            //2. Add components to database
            ////////////////////////////////////////////////////////////////////
            int adultAddSize = getSize(adultAddedList);
            int depAddSize = getSize(depAddedList);
            int addAddSize = getSize(addressAddedList);
            int moneyAddSize = getSize(moneyAddedList);
            int interestAddSize = getSize(interestAddedList);
            int historyAddSize = getSize(historyAddedList);

            //Add Adults
            boolean addAdults;
            for(int i = 0; i < adultAddSize; i++){
                addAdults = false;
                int index = adultAddedList.get(i);
                String[] adultAttribs = new String[adultTableModel.getColumnCount()-1];
                for(int j = 0; j < adultTableModel.getColumnCount()-1; j++){
                    adultAttribs[j] = (String)adultTableModel.getValueAt(index, j);
                }
                Adult adultObj = new Adult(adultAttribs[0],
                                           adultAttribs[1],
                                           adultAttribs[2],
                                           adultAttribs[3],adultAttribs[4],
                                           adultAttribs[5],adultAttribs[6],
                                           adultAttribs[7], adultAttribs[8],
                                           adultAttribs[9]);
                addAdults = dbManager.addRecord("", adultObj, familyKey);
                if(!addAdults){
                    addSaveError("an adult");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Add Dependents
            boolean addDeps;
            for(int i = 0; i < depAddSize; i++){
                addDeps = false;
                int index = depAddedList.get(i);
                String[] depAttribs = new String[dependentTableModel.getColumnCount()-1];
                for(int j = 0; j < dependentTableModel.getColumnCount()-1; j++){
                    depAttribs[j] = (String)dependentTableModel.getValueAt(index, j);
                }
                Dependent depObj = new Dependent(depAttribs[0],
                                           depAttribs[1],
                                           depAttribs[2],
                                           depAttribs[3],depAttribs[4],
                                           depAttribs[5],depAttribs[6]);
                addDeps = dbManager.addRecord("", depObj, familyKey);
                if(!addDeps){
                    addSaveError("a dependent");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Add Address
            boolean addAddress;
            for(int i = 0; i < addAddSize; i++){
                addAddress = false;
                int index = addressAddedList.get(i);
                Object[] addressAttribs = new Object[addressTableModel.getColumnCount()-1];
                for(int j = 0; j < addressTableModel.getColumnCount()-1; j++){
                    addressAttribs[j] = addressTableModel.getValueAt(index, j);
                }
                Address addObj = new Address((String)addressAttribs[0],
                                           (String)addressAttribs[1],
                                           (String)addressAttribs[2],
                                           (String)addressAttribs[3],(String)addressAttribs[4],
                                           (Boolean)addressAttribs[5],(String)addressAttribs[6]);
                addAddress = dbManager.addRecord("", addObj, familyKey);
                if(!addAddress){
                    addSaveError("an address");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Add Money
            boolean addContributions;
            for(int i = 0; i < moneyAddSize; i++){
                addContributions = false;
                int index = moneyAddedList.get(i);
                Object[] moneyAttribs = new Object[contributionTableModel.getColumnCount()-1];
                for(int j = 0; j < contributionTableModel.getColumnCount()-1; j++){
                    moneyAttribs[j] = contributionTableModel.getValueAt(index, j);
                }

                Money moneyObj = new Money((String)moneyAttribs[0],
                                           Double.parseDouble((String)moneyAttribs[1]),
                                           Double.parseDouble((String)moneyAttribs[2]),
                                           (String)moneyAttribs[3]);
                addContributions = dbManager.addRecord("", moneyObj, familyKey);
                if(!addContributions){
                    addSaveError("a money");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Add Interest
            boolean addInterests;
            for(int i = 0; i < interestAddSize; i++){
                addInterests = false;
                int index = interestAddedList.get(i);
                Object[] interestAttribs = new Object[ministryInterestTableModel.getColumnCount()-1];
                for(int j = 0; j < ministryInterestTableModel.getColumnCount()-1; j++){
                    interestAttribs[j] = ministryInterestTableModel.getValueAt(index, j);
                }
                Interest interestObj = new Interest((String)interestAttribs[0],
                                           (String)interestAttribs[1]);
                addInterests = dbManager.addRecord("interest", interestObj, familyKey);
                if(!addInterests){
                    addSaveError("a ministry interest");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Add History
            boolean addHistories;
            for(int i = 0; i < historyAddSize; i++){
                addHistories = false;
                int index = historyAddedList.get(i);
                Object[] historyAttribs = new Object[ministryHistoryTableModel.getColumnCount()-1];
                for(int j = 0; j < ministryHistoryTableModel.getColumnCount()-1; j++){
                    historyAttribs[j] = ministryHistoryTableModel.getValueAt(index, j);
                }
                History historyObj = new History((String)historyAttribs[0],
                                                 (String)historyAttribs[1]);
                addHistories = dbManager.addRecord("history", historyObj, familyKey);
                if(!addHistories){
                    addSaveError("a ministry history");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            ////////////////////////////////////////////////////////////////////
            //3. Update Components
            ////////////////////////////////////////////////////////////////////
            int adultUpdateSize = getSize(adultUpdatedList);
            int depUpdateSize = getSize(depUpdatedList);
            int addUpdateSize = getSize(addressUpdatedList);
            int moneyUpdateSize = getSize(moneyUpdatedList);
            int interestUpdateSize = getSize(interestUpdatedList);
            int historyUpdateSize = getSize(historyUpdatedList);

            //Update Family**************************************************************************************DO NOT NEED FOR LOOP HERE!!!!
            boolean updateFamily;
            for(int i = 0; i < 1; i++){
                updateFamily = false;
                Object[] familyAttribs = new Object[familyTableModel.getColumnCount()];
                for(int j = 0; j < familyTableModel.getColumnCount(); j++){
                    familyAttribs[j] = familyTableModel.getValueAt(0, j);
                }//for
                Family familyObj = new Family((String)familyAttribs[0],
                                           (String)familyAttribs[1],
                                           (String)familyAttribs[2],
                                           (Boolean)familyAttribs[3],(Boolean)familyAttribs[4],
                                           (String)familyAttribs[5],(String)familyAttribs[6]);
                updateFamily = dbManager.updateRecord("",family,familyObj, familyKey);
                if(!updateFamily){
                    updateSaveError("a family");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Update Adults
            boolean updateAdults;
            for(int i = 0; i < adultUpdateSize; i++){
                updateAdults = false;
                int index = adultUpdatedList.get(i);
                String[] adultAttribs = new String[adultTableModel.getColumnCount()-1];
                for(int j = 0; j < adultTableModel.getColumnCount()-1; j++){
                    adultAttribs[j] = (String)adultTableModel.getValueAt(index, j);
                }
                Adult adultObj = new Adult(adultAttribs[0],
                                           adultAttribs[1],
                                           adultAttribs[2],
                                           adultAttribs[3],adultAttribs[4],
                                           adultAttribs[5],adultAttribs[6],
                                           adultAttribs[7], adultAttribs[8],
                                           adultAttribs[9]);
                //Get the original Adult in the adult ArrayList at the row index
                //in the adultUpdatedList
                Adult oldAdultObj = adult.get(index);
                updateAdults = dbManager.updateRecord("",oldAdultObj,adultObj, familyKey);
                if(!updateAdults){
                    updateSaveError("an adult");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Update Dependents
            boolean updateDeps;
            for(int i = 0; i < depUpdateSize; i++){
                updateDeps = false;
                int index = depUpdatedList.get(i);
                String[] depAttribs = new String[dependentTableModel.getColumnCount()-1];
                for(int j = 0; j < dependentTableModel.getColumnCount()-1; j++){
                    depAttribs[j] = (String)dependentTableModel.getValueAt(index, j);
                }
                Dependent depObj = new Dependent(depAttribs[0],
                                           depAttribs[1],
                                           depAttribs[2],
                                           depAttribs[3],depAttribs[4],
                                           depAttribs[5],depAttribs[6]);
                //Get the original Dependent in the Dep ArrayList at the row index
                //in the depUpdatedList
                Dependent oldDepObj = dependent.get(index);
                updateDeps = dbManager.updateRecord("",oldDepObj, depObj, familyKey);
                if(!updateDeps){
                    updateSaveError("a dependent");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Update Address
            boolean updateAddress;
            for(int i = 0; i < addUpdateSize; i++){
                updateAddress = false;
                int index = addressUpdatedList.get(i);
                Object[] addressAttribs = new Object[addressTableModel.getColumnCount()-1];
                for(int j = 0; j < addressTableModel.getColumnCount()-1; j++){
                    addressAttribs[j] = addressTableModel.getValueAt(index, j);
                }
                Address addObj = new Address((String)addressAttribs[0],
                                           (String)addressAttribs[1],
                                           (String)addressAttribs[2],
                                           (String)addressAttribs[3],(String)addressAttribs[4],
                                           (Boolean)addressAttribs[5],(String)addressAttribs[6]);
                //Get the original Address in the address ArrayList at the row index
                //in the addressUpdatedList
                Address oldAddressObj = address.get(index);
                updateAddress = dbManager.updateRecord("",oldAddressObj, addObj, familyKey);
                if(!updateAddress){
                    updateSaveError("an address");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Update Money
            boolean updateContributions;
            for(int i = 0; i < moneyUpdateSize; i++){
                updateContributions = false;
                int index = moneyUpdatedList.get(i);
                Object[] moneyAttribs = new Object[contributionTableModel.getColumnCount()-1];
                for(int j = 0; j < contributionTableModel.getColumnCount()-1; j++){
                    moneyAttribs[j] = contributionTableModel.getValueAt(index, j);
                }
                Money moneyObj = new Money((String)moneyAttribs[0],
                                           Double.parseDouble((String)moneyAttribs[1]),
                                           Double.parseDouble((String)moneyAttribs[2]),
                                           (String)moneyAttribs[3]);
                //Get the original Money in the money ArrayList at the row index
                //in the moneyUpdatedList
                Money oldMoneyObj = money.get(index);
                updateContributions = dbManager.updateRecord("",oldMoneyObj, moneyObj, familyKey);
                if(!updateContributions){
                    updateSaveError("a money");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Update Interests
            boolean updateInterests;
            for(int i = 0; i < interestUpdateSize; i++){
                updateInterests = false;
                int index = interestUpdatedList.get(i);
                Object[] interestAttribs = new Object[ministryInterestTableModel.getColumnCount()-1];
                for(int j = 0; j < ministryInterestTableModel.getColumnCount()-1; j++){
                    interestAttribs[j] = ministryInterestTableModel.getValueAt(index, j);
                }
                Interest interestObj = new Interest((String)interestAttribs[0],
                                                 (String)interestAttribs[1]);
                //Get the original Interests in the Interests ArrayList at the row index
                //in the interestUpdatedList
                Interest oldInterestObj = interests.get(index);
                updateInterests = dbManager.updateRecord("interest",oldInterestObj, interestObj, familyKey);
                if(!updateInterests){
                    updateSaveError("a ministry interest");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Update Histories
            boolean updateHistories;
            for(int i = 0; i < historyUpdateSize; i++){
                updateHistories = false;
                int index = historyUpdatedList.get(i);
                Object[] historyAttribs = new Object[ministryHistoryTableModel.getColumnCount()-1];
                for(int j = 0; j < ministryHistoryTableModel.getColumnCount()-1; j++){
                    historyAttribs[j] = ministryHistoryTableModel.getValueAt(index, j);
                }
                History historyObj = new History((String)historyAttribs[0],
                                                 (String)historyAttribs[1]);
                //Get the original History in the histories ArrayList at the row index
                //in the historyUpdatedList
                History oldHistoryObj = histories.get(index);
                updateHistories = dbManager.updateRecord("history",oldHistoryObj, historyObj, familyKey);
                if(!updateHistories){
                    updateSaveError("a ministry history");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            ///////////////////////////////////////////////////////////////////
            //Save Successful
            ///////////////////////////////////////////////////////////////////
            saveSuccessful = dbManager.commitAll();
            if(saveSuccessful){
                JOptionPane.showMessageDialog(null,"Save successful!", "Save",
                    JOptionPane.INFORMATION_MESSAGE);
                this.dispose();//close window
            }//if
            else{
                JOptionPane.showMessageDialog(null, "Sorry, the save was not successful due to an error" + "\n"
                        + "Please contact your Database Administrator, a.k.a Thomas Naps, for help if this persists.",
                        "Database Saving Error", JOptionPane.ERROR_MESSAGE);
            }
        }//try
        catch(Exception ex){
            JOptionPane.showMessageDialog(null, "Sorry, the save cannot continue due to an error" + "\n" +
                    "Please contact your Database Administrator, a.k.a Thomas Naps, for help if this persists."
                    + "\n" + "EditHouseholdGui.java: save() Method.",
                    "Database Saving Error", JOptionPane.ERROR_MESSAGE);
            ex.getMessage();
            ex.printStackTrace();
        }//catch
    }//save()

    /**
     * Save error message for deleting objects from the database
     * @param classification - string either "adult", "dependent","ministry interest",
     * "contribution", "ministry history", or "address"
     */
    private void deleteSaveError(String classification){
        if(classification.equalsIgnoreCase("family")){
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "deleting this " + classification + "record"
                            + " from the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }else{
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "deleting a " + classification + "record"
                            + " from the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }//else
    }

    /**
     * Save error message for added objects from the database
     * @param classification - string either "adult", "dependent","ministry interest",
     * "contribution", "ministry history", or "address"
     */
    private void addSaveError(String classification){
        if(classification.equalsIgnoreCase("family")){
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "adding this " + classification + "record"
                            + " to the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }else{
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "adding " + classification + " record"
                            + " to the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }//else
    }

    /**
     * Save error message for updated objects from the database
     * @param classification - string either "adult", "dependent","ministry interest",
     * "contribution", "ministry history", or "address"
     */
    private void updateSaveError(String classification){
        if(classification.equalsIgnoreCase("family")){
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "updating this " + classification + "record"
                            + " to the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }else{
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "updating " + classification + " record"
                            + " to the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }//else
    }

    /**
     * Gets the size of the arraylist so that it is not null if the
     * the arraylist is empty
     * @param arrayList - the arraylist needing a size.
     * @return int - returns 0 if it is empty, 1,2,.. if it is not empty.
     */
    private int getSize(ArrayList arrayList){
        int size;
        if(arrayList.isEmpty()){
            size = 0;
        }//if
        else{
            size = arrayList.size();
        }//else
        return size;
    }//getSize()

    /**
     * Method to Verify State Fields in address
     */
    private boolean verifyZipFields(){
        int zipCount = 0;
        boolean zip = false;

        //Address Tab
        for(int i = 0; i < addressTableModel.getRowCount(); i++){
            String zipField = (String)addressTableModel.getValueAt(i, 3);
            //if zipcode is not empty and the row is not deleted
            if(!zipField.equalsIgnoreCase("") && !(Boolean)addressTableModel.getValueAt(i, addressTableModel.getColumnCount()-1)){
                if(zipField.length() > 10){
                    zipCount ++;
                }//if
            }//if
        }//for

        if(zipCount != 0){
            zip = false;
        }
        else{
            zip = true;
        }

        return zip;

    }//verifyStateFields()

    /**
     * Method to Verify State Fields in address
     */
    private boolean verifyStateFields(){
        int stateCount = 0;
        boolean state = false;

        //Address Tab
        for(int i = 0; i < addressTableModel.getRowCount(); i++){
            String stateField = (String)addressTableModel.getValueAt(i, 2);
            //if state is not empty and if the row is not deleted
            if(!stateField.equalsIgnoreCase("") && !(Boolean)addressTableModel.getValueAt(i, addressTableModel.getColumnCount()-1)){
                if(stateField.length()!= 2){
                    stateCount ++;
                }//if
            }//if
        }//for

        if(stateCount != 0){
            state = false;
        }
        else{
            state = true;
        }

        return state;

    }//verifyStateFields()

    /**
     * Method to Verify all date fields are in correct format
     *
     * @return String of Tabs that do not have proper
     * date format
     */
    private String verifyPhoneFields(){
        int adultCount = 0;
        int depCount = 0;
        int famCount = 0;
        String phones = "";

        //Adult Tab
        for(int i = 0; i < adultTableModel.getRowCount(); i++){
            String phone1 = (String)adultTableModel.getValueAt(i, 6);
            String phone2 = (String)adultTableModel.getValueAt(i, 7);
            //if phones are empty and the row is not deleted
            if(!phone1.equalsIgnoreCase("") && phone1.length()!=13 &&
                    !(Boolean)adultTableModel.getValueAt(i, adultTableModel.getColumnCount()-1)){
                    adultCount ++;
            }//if
            if(!phone2.equalsIgnoreCase("") && phone2.length()!=13 &&
                    !(Boolean)adultTableModel.getValueAt(i, adultTableModel.getColumnCount()-1)){
                    adultCount ++;
            }//if
        }//for

        //Dependent
        //if Dependent Rows Exist
        if(dependentTableModel.getRowCount() > 0){
            for(int i = 0; i < dependentTableModel.getRowCount(); i++){
                String phone3 = (String)dependentTableModel.getValueAt(i, 5);
                if(!phone3.equalsIgnoreCase("") && !(Boolean)dependentTableModel.getValueAt(i, dependentTableModel.getColumnCount()-1)){
                    if(phone3.length()!= 13){
                        depCount ++;
                    }//if
                }//if
            }//for
        }//if-rowCount

        //Family
        for(int i = 0; i < familyTableModel.getRowCount(); i++){
            String phone4 = (String)familyTableModel.getValueAt(i, 1);
            if(!phone4.equalsIgnoreCase("")){
                if(phone4.length()!= 13){
                    famCount ++;
                }//if
            }//if
        }//for

        if(adultCount != 0){
            phones = phones + "\n" + "Adult Tab";
        }//if
        if(depCount !=0){
            phones = phones + "\n" + "Dependent Tab";
        }//if
        if(famCount != 0){
            phones = phones + "\n" + "Family Tab";
        }//if

        return phones;

    }//verifyPhoneFields();

    /**
     * Method to Verify all date fields are in correct format
     *
     * @return String of Tabs that do not have proper
     * date format
     */
    private String verifyDateFields(){
        int adultCount = 0;
        int depCount = 0;
        int historyCount = 0;
        String dates = "";

        //Adult Tab
        for(int i = 0; i < adultTableModel.getRowCount(); i++){
            //Field is required, don't allow empty string.
            if(!Validator.isDate((String)adultTableModel.getValueAt(i, 2))
                    && !(adultTableModel.getValueAt(i, 2).toString().trim()).equalsIgnoreCase("")
                    && !(Boolean)adultTableModel.getValueAt(i, adultTableModel.getColumnCount()-1)){
                adultCount++;
            }//if
            //Field is not required, allow empty string.
            if(!Validator.isDate((String)adultTableModel.getValueAt(i, 3))
                    && !(adultTableModel.getValueAt(i, 3).toString().trim()).equalsIgnoreCase("")
                    && !(Boolean)adultTableModel.getValueAt(i, adultTableModel.getColumnCount()-1)){
                adultCount++;
            }//if
        }//for

        //Dependent
        for(int i = 0; i < dependentTableModel.getRowCount(); i++){
            //Check each row for column 2 (primary keys) if row is not deleted
            if(!Validator.isDate((String)dependentTableModel.getValueAt(i,2))
                    && !(dependentTableModel.getValueAt(i,2).toString().trim()).equalsIgnoreCase("")
                    && !(Boolean)dependentTableModel.getValueAt(i, dependentTableModel.getColumnCount()-1))
            {
                depCount ++;
            }//if
        }//for

        //Ministry History
        //if ministry history rows exist
        if(ministryHistoryTableModel.getRowCount() > 0){
            for(int i = 0; i < ministryHistoryTableModel.getRowCount(); i++){
                //Check each row for column 1,2,3 (primary keys)
                if(!Validator.isDate(((String)ministryHistoryTableModel.getValueAt(i,1)))
                        && !((String)ministryHistoryTableModel.getValueAt(i,1)).equalsIgnoreCase("")
                        && !(Boolean)ministryHistoryTableModel.getValueAt(i, ministryHistoryTableModel.getColumnCount()-1))
                {
                    historyCount ++;
                }//if
            }//for
        }//if-rowcount

        if(adultCount != 0){
            dates = dates + "\n" + "Adult Tab";
        }//if
        if(depCount !=0){
            dates = dates + "\n" + "Dependent Tab";
        }//if
        if(historyCount != 0){
            dates = dates + "\n" + "Ministry History Tab";
        }//if

        return dates;

    }//verifyDateFields();

   /**
    * Check for duplicates within each tab
    * @return boolean false if there are duplicates; true if there is no duplicates
    * @param TableModel tableModel is the table model of the tab you want to check duplicates of
    * @param Int primaryKey is the size of the primary key of the table
    */
    private boolean checkDups(TableModel tableModel, int primaryKey){
        int rowCount = tableModel.getRowCount();

        boolean noDuplicates = true;

        Outer:
        for(int i = 0; i < rowCount; i++){
            int equalColumnCount = 0;
            //check first three columns
            for(int k = 0; k <= rowCount && k != i; k++){
                for(int j = 0; j < primaryKey; j++){
                    if(tableModel.getValueAt(i, j).toString().toLowerCase().equals(tableModel.getValueAt(k, j).toString().toLowerCase())
                            && ((Boolean)tableModel.getValueAt(i, tableModel.getColumnCount()-1) == false)
                            && ((Boolean)tableModel.getValueAt(k, tableModel.getColumnCount()-1) == false))
                    {
                        equalColumnCount++;
                    }//if
                }//for-j

                if(equalColumnCount == primaryKey){
                    noDuplicates = false;
                    break Outer;
                }//if
                equalColumnCount = 0;
            }//for-k
        }//for-i
        return noDuplicates;
    }

    /**
     * Check for duplicates between Adults & Existing Dependents tab
     * @return boolean - false = duplicates; true = no duplicates
     */
    private boolean adultAndDepDuplicates(){

        int adultRowCount = adultTableModel.getRowCount();
        int depRowCount = dependentTableModel.getRowCount();
        int primaryKey = 3;

        boolean noDuplicates = true;

        Outer:
        for(int i = 0; i < adultRowCount; i++){
            int equalColumnCount = 0;

            //check first three columns
            for(int k = 0; k < depRowCount; k++){
                for(int j = 0; j < primaryKey; j++){
                    if(adultTableModel.getValueAt(i, j).toString().toLowerCase().equals(dependentTableModel.getValueAt(k, j).toString().toLowerCase())
                            && ((Boolean)adultTableModel.getValueAt(i, adultTableModel.getColumnCount()-1) == false)
                            && ((Boolean)dependentTableModel.getValueAt(k, dependentTableModel.getColumnCount()-1) == false) ){
                        equalColumnCount++;
                    }//if
                }//for-j

                if(equalColumnCount == primaryKey){
                    noDuplicates = false;
                    break Outer;
                }

                equalColumnCount = 0;
            }//for-k

        }//for-i
        return noDuplicates;
    }//adultAndDepDuplicates

    /**
     * Method to verify no duplicate rows among the different tabs
     * @return String of Tabs that have duplicate rows
     */
    private String verifyDuplicateRows(){
        //do not need to check duplicates in family because
        //you can only add one row.
        boolean adultDups = checkDups(adultTableModel,3);
        boolean depDups = checkDups(dependentTableModel,3);
        boolean addDups = checkDups(addressTableModel,4);
        boolean contrDups = checkDups(contributionTableModel,1);
        boolean interestDups = checkDups(ministryInterestTableModel,1);//ministry name is primary key
        boolean historyDups = checkDups(ministryHistoryTableModel,2);//name and date is primary key
        boolean adultAndDep = adultAndDepDuplicates();

        String dupTabs = "";

        if(adultDups && depDups && addDups && contrDups
                && interestDups && historyDups && adultAndDep){
            //do nothing
        }//if
        else{
            if(!adultDups){
                dupTabs = dupTabs + "\n" + "Adult Tab:"
                        + " Unique fields are the First Name, "
                        + "Last Name, and Date of Birth.";
            }//if
            if(!depDups){
                dupTabs = dupTabs + "\n" + "New Dependent Tab:"
                        + " Unique fields are the First Name, "
                        + "Last Name, and Date of Birth.";
            }//if
            if(!addDups){
                dupTabs = dupTabs + "\n" + "Address Tab:"
                        + " Unique fields are the Street, "
                        + "City, State, and Zipcode.";
            }//if
            if(!contrDups){
                dupTabs = dupTabs + "\n" + "Contribution Tab:"
                        + " Unique field is the Year.";
            }//if
            if(!interestDups){
                dupTabs = dupTabs + "\n" + "Ministry Interest Tab:"
                        + " Unique field is the Ministry Name.";
            }//if
            if(!historyDups){
                dupTabs = dupTabs + "\n" + "Ministry History Tab:"
                        + " Unique fields are the Ministry Name and Date.";
            }//if
            if(!adultAndDep){
                dupTabs = dupTabs + "\n" + "Rows in the Adult and Dependent Tabs share the same unique fields.";
            }
        }//else

        return dupTabs;
    }

    /**
     * Method to verify all required fields are complete
     *
     * @return String of Tabs that do not have completed required fields
     */
    private String verifyRequiredFields(){
        //Check Required fields of each tab then clear for another entry
        boolean adultSave = checkAdultTab();
        boolean dependentSave = checkDepTab();
        boolean familySave = checkFamTab();
        boolean addressSave = checkAddTab();
        boolean contributionsSave = checkMoneyTab();
        boolean ministryInterestSave = checkInterestTab();
        boolean ministryHistorySave = checkHistoryTab();

        String nullTabs = "";

        if(adultSave && dependentSave && familySave && addressSave &&
                ministryInterestSave && ministryHistorySave &&
                contributionsSave){
            //do nothing
        }//if
        else{
            if(!adultSave){
                nullTabs = nullTabs + "\n" + "Adult Tab";
            }//if
            if(!dependentSave){
                nullTabs = nullTabs + "\n" + "Dependent Tab";
            }//if
            if(!familySave){
                nullTabs = nullTabs + "\n" + "Family Tab";
            }//if
            if(!addressSave){
                nullTabs = nullTabs + "\n" + "Address Tab";
            }//if
            if(!contributionsSave){
                nullTabs = nullTabs + "\n" + "Contributions Tab";
            }//if
            if(!ministryInterestSave){
                nullTabs = nullTabs + "\n" + "Ministry Interest Tab";
            }//if
            if(!ministryHistorySave){
                nullTabs = nullTabs + "\n" + "Ministry History Tab";
            }//if
        }//else
        return nullTabs;
    }//verifyRequiredFields

    /**
     * Checks the Adult Tab if all
     * required fields are complete
     */
    private boolean checkAdultTab(){
        boolean adultSave = false;
        int nullCount = 0;
        //check adult
        for(int i = 0; i < adultTableModel.getRowCount(); i++){
            //Check each row for column 1,2,3 (primary keys)
            if(adultTableModel.getValueAt(i,0).equals("")
                    | adultTableModel.getValueAt(i,1).equals("")
                    | adultTableModel.getValueAt(i,2).equals("")
                    && !(Boolean)adultTableModel.getValueAt(i, adultTableModel.getColumnCount()-1))
            {
                nullCount ++;
            }//if
        }//for

        if(nullCount != 0){
            adultSave = false;
        }//if
        else{
            adultSave = true;
        }//else
        return adultSave;

    }//checkAdultTab()

    /**
     * Checks the Dependent Tab if all
     * required fields are complete
     */
    private boolean checkDepTab(){
        boolean depSave = false;
        int nullCount = 0;
        //check Dependent rows, if they exist
        if(dependentTableModel.getRowCount() > 0){
            for(int i = 0; i < dependentTableModel.getRowCount(); i++){
                //Check each row for required fields
                if(dependentTableModel.getValueAt(i,0).equals("")
                        | dependentTableModel.getValueAt(i,1).equals("")
                        | dependentTableModel.getValueAt(i,2).equals("")
                        && !(Boolean)dependentTableModel.getValueAt(i, dependentTableModel.getColumnCount()-1))
                {
                    nullCount ++;
                }//if
            }//for
        }//if

        if(nullCount != 0){
            depSave = false;
        }//if
        else{
            depSave = true;
        }//else
        return depSave;
    }//checkDepTab()

    /**
     * Checks the Family Tab if all
     * required fields are complete
     */
    private boolean checkFamTab(){
        boolean famSave = false;
        int nullCount = 0;
        //check adult
        for(int i = 0; i < familyTableModel.getRowCount(); i++){
            //Check each row for required fields
            if(familyTableModel.getValueAt(i,0).equals("")
                    | familyTableModel.getValueAt(i,1).equals("")
                    | familyTableModel.getValueAt(i,2).equals("")
                    | familyTableModel.getValueAt(i, 5).equals(""))
            {
                nullCount ++;
            }//if
        }//for

        if(nullCount != 0){
            famSave = false;
        }//if
        else{
            famSave = true;
        }//else
        return famSave;

    }//checkFamilyTab()

    /**
     * Checks the Address Tab if all
     * required fields are complete
     */
    private boolean checkAddTab(){
        boolean addressSave = false;
        int nullCount = 0;
        //check address
        for(int i = 0; i < addressTableModel.getRowCount(); i++){
            //Check each row for required fields
            if(addressTableModel.getValueAt(i,0).equals("")
                    | addressTableModel.getValueAt(i,1).equals("")
                    | addressTableModel.getValueAt(i,2).equals("")
                    | addressTableModel.getValueAt(i,3).equals("")
                    && !(Boolean)addressTableModel.getValueAt(i, addressTableModel.getColumnCount()-1))
            {
                nullCount ++;
            }//if
        }//for

        if(nullCount != 0){
            addressSave = false;
        }//if
        else{
            addressSave = true;
        }//else
        return addressSave;

    }//checkAddTab()

    /**
     * Checks the Contribution Tab if all
     * required fields are complete
     */
    private boolean checkMoneyTab(){
        boolean moneySave = false;
        int nullCount = 0;
        //check Money, if rows exist
        if(contributionTableModel.getRowCount() > 0){
            for(int i = 0; i < contributionTableModel.getRowCount(); i++){
                //Check each row for required fields
                if(contributionTableModel.getValueAt(i,0).equals("")
                        && !(Boolean)contributionTableModel.getValueAt(i, contributionTableModel.getColumnCount()-1))
                {
                    nullCount ++;
                }//if
            }//for
        }//if

        if(nullCount != 0){
            moneySave = false;
        }//if
        else{
            moneySave = true;
        }//else
        return moneySave;
    }//checkMoneyTab()

    /**
     * Verify money format in the
     * Year to date and pledged fields to be sure they
     * are of double format
     */
    private boolean verifyMoneyFormat(){
        boolean moneySave = false;
        int formatCount = 0;
        //check Money, if rows exist
        if(contributionTableModel.getRowCount() > 0){
            for(int i = 0; i < contributionTableModel.getRowCount(); i++){
                //Check each row for money fields
                if(!Validator.isMoney((String)contributionTableModel.getValueAt(i,1))
                        && ((Boolean)contributionTableModel.getValueAt(i, contributionTableModel.getColumnCount()-1)==false))
                {
                    formatCount ++;
                }//if
                if(!Validator.isMoney((String)contributionTableModel.getValueAt(i,2))
                        && ((Boolean)contributionTableModel.getValueAt(i, contributionTableModel.getColumnCount()-1)==false))
                {
                    formatCount ++;
                }//if
            }//for
        }//if

        if(formatCount != 0){
            moneySave = false;
        }//if
        else{
            moneySave = true;
        }//else
        return moneySave;
    }//verifyMoneyFormat()
    /**
     * Checks the Interest Tab if all
     * required fields are complete
     */
    private boolean checkInterestTab(){
        boolean interestSave = false;
        int nullCount = 0;
        //check Interest, if rows exist
        if(ministryInterestTableModel.getRowCount() > 0){
            for(int i = 0; i < ministryInterestTableModel.getRowCount(); i++){
                //Check each row for required fields
                if(ministryInterestTableModel.getValueAt(i,0).equals("")
                        && !(Boolean)ministryInterestTableModel.getValueAt(i, ministryInterestTableModel.getColumnCount()-1))
                {
                    nullCount ++;
                }//if
            }//for
        }//if

        if(nullCount != 0){
            interestSave = false;
        }//if
        else{
            interestSave = true;
        }//else
        return interestSave;
    }//checkInterestTab()

    /**
     * Checks the History Tab if all
     * required fields are complete
     */
    private boolean checkHistoryTab(){
        boolean historySave = false;
        int nullCount = 0;
        //check Money, if rows exist
        if(ministryHistoryTableModel.getRowCount() > 0){
            for(int i = 0; i < ministryHistoryTableModel.getRowCount(); i++){
                //Check each row for required fields
                if(ministryHistoryTableModel.getValueAt(i,0).equals("")
                        |ministryHistoryTableModel.getValueAt(i,1).equals("")
                        && !(Boolean)ministryHistoryTableModel.getValueAt(i, ministryHistoryTableModel.getColumnCount()-1))
                {
                    nullCount ++;
                }//if
            }//for
        }//if

        if(nullCount != 0){
            historySave = false;
        }//if
        else{
            historySave = true;
        }//else
        return historySave;
    }//checkHistoryTab()

   /**
    *
    * @param type - Classification of object: "adults", "dependents", "families",
    * "addresses" or "ministries".
    * @param key - primary key of object
    * @return boolean - true if item does exist in database, false if it does not.
    */
    private boolean itemDoesExist(String type, String[] key){
        boolean doesExist = false;
        try{
            DBManager dbManager = new DBManager();
            doesExist = dbManager.doesExist(type, key);
        }//try
        catch(Exception ex){
            ex.printStackTrace();
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "verifying a record in the database." +"\n"+
                "Please contact your Database Administrator, a.k.a Thomas Naps, for help if this persists."
                + "\n" + "(EditHouseholdGui.java: itemDoesExist() method)",
                "Database Error", JOptionPane.ERROR_MESSAGE);
        }//catch
        if(doesExist == true){
                return true;
        }//if
        else{
            return false;
        }//else
    }//itemDoesExist()

    /**
     * Method to verify the added row items aren't already in the database
     * @return String - returns string of rows and tabs that have duplicate information.
     */
    private String verifyAddedItemsExist(){
        String rowsWithDups = "";

        //Check Adult Tab
        for(int i = 0; i < adultTableModel.getRowCount(); i++){
            if((Boolean)adultTableModel.getValueAt(i, adultTableModel.getColumnCount()-1)==false &&
                    adultAddedList.contains((Integer)i)){
               String[] adultKey = {(String)adultTableModel.getValueAt(i, 0),
                                    (String)adultTableModel.getValueAt(i, 1),
                                    (String)adultTableModel.getValueAt(i, 2)};
               boolean doesExist = itemDoesExist("adults", adultKey);
               if(doesExist){
                  rowsWithDups = rowsWithDups + "Adult Tab Row: " + (i + 1) + "\n";
               }//if
            }//if
        }//for

        //check Dependent Tab
        for(int i = 0; i < dependentTableModel.getRowCount(); i++){
            if((Boolean)dependentTableModel.getValueAt(i, dependentTableModel.getColumnCount()-1)==false
                    && depAddedList.contains((Integer)i)){
                String[] depKey = {(String)dependentTableModel.getValueAt(i, 0),
                                    (String)dependentTableModel.getValueAt(i, 1),
                                    (String)dependentTableModel.getValueAt(i, 2)};
                boolean doesExist = itemDoesExist("dependents", depKey);
                if(doesExist){
                   rowsWithDups = rowsWithDups + "Dependent Tab Row: " + (i+1) + "\n";
                }//if
            }//if
        }//for

//        //Check Family Tab
//        //get family key
//        String[] currentFamKey = {(String)familyTableModel.getValueAt(0, 0),
//                              (String)familyTableModel.getValueAt(0, 1)};
//        boolean doesExist = itemDoesExist("families", currentFamKey);
//        if(doesExist){
//            rowsWithDups = rowsWithDups + "Family Tab Row: " + 1 + "\n";
//        }//if
        return rowsWithDups;
    }//verifyAddedItemsExist()

    private String verifyUpdatedItemsExist(){
        String rowsWithDups = "";

        //Check Adult Tab
        //if The primary keys of the current adult record, and original adult record are different,
        //check the database to see if the updated record exists, if not, then string is empty.
        for(int i = 0; i < adultTableModel.getRowCount(); i++){
            if((Boolean)adultTableModel.getValueAt(i, adultTableModel.getColumnCount()-1)==false &&
                    adultUpdatedList.contains((Integer)i)){
               //get original adult data
               String[] origAdult = (String[])adult.get(i).getAttributes();
               //get current adult data
               String[] adultKey = {(String)adultTableModel.getValueAt(i, 0),
                                    (String)adultTableModel.getValueAt(i, 1),
                                    (String)adultTableModel.getValueAt(i, 2)};
               if(!origAdult[0].equalsIgnoreCase(adultKey[0])
                       && !origAdult[1].equalsIgnoreCase(adultKey[1])
                       && !origAdult[2].equalsIgnoreCase(adultKey[2])){
                   boolean doesExist = itemDoesExist("adults", adultKey);
                   if(doesExist){
                       rowsWithDups = rowsWithDups + "Adult Tab Row: " + (i + 1) + "\n";
                   }//if
               }//if
            }//if
        }//for

        //Check Dependent Tab
        for(int i = 0; i < dependentTableModel.getRowCount(); i++){
            if((Boolean)dependentTableModel.getValueAt(i, dependentTableModel.getColumnCount()-1)==false &&
                    depUpdatedList.contains((Integer)i)){
               //get original dep data
               String[] origDep = (String[])dependent.get(i).getAttributes();
               //get current dependent data
               String[] depKey = {(String)dependentTableModel.getValueAt(i, 0),
                                    (String)dependentTableModel.getValueAt(i, 1),
                                    (String)dependentTableModel.getValueAt(i, 2)};
               if(!origDep[0].equalsIgnoreCase(depKey[0])
                       && !origDep[1].equalsIgnoreCase(depKey[1])
                       && !origDep[2].equalsIgnoreCase(depKey[2])){
                   boolean doesExist = itemDoesExist("dependents", depKey);
                   if(doesExist){
                       rowsWithDups = rowsWithDups + "Dependent Tab Row: " + (i + 1) + "\n";
                   }//if
               }//if
            }//if
        }//for

        //Check Family Tab
        //get family key
        String[] currentFamKey = {(String)familyTableModel.getValueAt(0, 0),
                              (String)familyTableModel.getValueAt(0, 1)};
        if(!familyKey[0].equalsIgnoreCase(currentFamKey[0])
                && !familyKey[1].equalsIgnoreCase(currentFamKey[1])){
            boolean doesExist = itemDoesExist("families", currentFamKey);
            if(doesExist){
                rowsWithDups = rowsWithDups + "Family Tab Row: " + 1 + "\n";
            }//if
        }//if
        return rowsWithDups;
    }//verifyItemsExist()

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btAddRow;
    private javax.swing.JButton btCancel;
    private javax.swing.JButton btDeleteHousehold;
    private javax.swing.JButton btEditInd;
    private javax.swing.JButton btRemoveRow;
    private javax.swing.JButton btSave;
    private javax.swing.JScrollPane jAddressTab;
    private javax.swing.JTable jAddressTable;
    private javax.swing.JTable jAdultTable;
    private javax.swing.JTable jContributionTable;
    private javax.swing.JScrollPane jContributionsTab;
    private javax.swing.JTable jDependentTable;
    private javax.swing.JScrollPane jDependentsTab;
    private javax.swing.JTable jFamilyInformationTable;
    private javax.swing.JScrollPane jFamilyTab;
    private javax.swing.JTable jMinistryHistoryTable;
    private javax.swing.JScrollPane jMinistryInterestTab;
    private javax.swing.JTable jMinistryInterestTable;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JLabel lblAddNewHousehold;
    private javax.swing.JScrollPane tabAdult;
    private javax.swing.JTabbedPane tabbedPane;
    // End of variables declaration//GEN-END:variables

    private TableModel adultTableModel = new TableModel(
                                    new Object [][] {
                                        {"","","","","","","","","","",false}
                                    },
                                    new String [] {
                                        "First Name*", "Last Name*", "Birthdate*",
                                        "Date Joined", "Occupation","Employer",
                                        "Work Phone","Personal Phone","E-Mail",
                                        "Notes","Deleted"
                                    }
                                );
    private TableModel dependentTableModel = new TableModel(
                                    new Object [][] {
                                        {"","","","","","","",false}
                                    },
                                    new String [] {
                                        "First Name*", "Last Name*", "Birthdate*",
                                        "School", "Religious Schooling",
                                        "Personal Phone","Notes", "Deleted"});

    private TableModel familyTableModel = new TableModel(
                                    new Object [][] {
                                        {"","","",false, false,"",""}
                                    },
                                    new String [] {
                                        "Family Name*",
                                        "Primary Phone*",
                                        "Head of Household*",
                                        "Send Donation Letter?",
                                        "Send Volunteer Letter?",
                                        "Salutation","Notes"});

    private TableModel addressTableModel = new TableModel(
                                    new Object [][] {
                                        {"","","","","", false,"",false}
                                    },
                                    new String [] {
                                        "Street*", "City*", "State*",
                                        "Zipcode*", "Municipal",
                                        "Current Mailing Address?","Notes","Deleted"});

        private TableModel contributionTableModel = new TableModel(
                                    new Object [][] {
                                        {"","","","",false}
                                    },
                                    new String [] {
                                        "Year*", "Pledged Amount", "Year-to-Date",
                                        "Notes","Deleted"});

        private TableModel ministryInterestTableModel = new TableModel(
                                    new Object [][] {
                                        {"","",false}
                                    },
                                    new String [] {
                                        "Ministry Name*", "Availability","Deleted"});

        private TableModel ministryHistoryTableModel = new TableModel(
                                    new Object [][] {
                                        {"","",false}
                                    },
                                    new String [] {
                                        "Ministry Name*","Date*","Deleted"});
}//EditHouseholdGui
